package com.github.davidfantasy.mybatisplus.generatorui;

import cn.hutool.core.util.StrUtil;
import com.github.davidfantasy.mybatisplus.generatorui.mbp.NameConverter;
import com.google.common.base.Strings;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration;
import org.springframework.boot.autoconfigure.web.servlet.*;
import org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Import;


import java.util.HashMap;
import java.util.Map;
import java.util.Optional;


/**
 * 不使用@SpringBootApplication和@EnableAutoConfiguration
 * 注解，避免启动时被宿主系统的自动配置所干扰，直接注入需要的配置类
 */
@SpringBootConfiguration
@Import({
        DispatcherServletAutoConfiguration.class,
        ServletWebServerFactoryAutoConfiguration.class,
        HttpEncodingAutoConfiguration.class,
        HttpMessageConvertersAutoConfiguration.class,
        MultipartAutoConfiguration.class,
        ErrorMvcAutoConfiguration.class,
        WebMvcAutoConfiguration.class})
@ComponentScan("com.github.davidfantasy.mybatisplus.generatorui")
@Slf4j
public class MybatisPlusToolsApplication {

    public static GeneratorConfig generatorConfig;

    public static void main(String[] args) {
        // com.mysql.cj.jdbc.Driver       oracle.jdbc.driver.OracleDriver
        String driverClassName = getArgsStr(args, 0,"oracle.jdbc.driver.OracleDriver");
        // jdbc:mysql://localhost:3306/db       jdbc:oracle:thin:@10.3.87.68:1521/wms
        String jdbcUrl = getArgsStr(args, 1, "jdbc:oracle:thin:@10.3.87.68:1521/wms");
        String schemaName = getArgsStr(args, 2, "WMS_HZ");
        String userName = getArgsStr(args, 3,"wms_hz");
        String password = getArgsStr(args, 4,"JzTwmShz2023");
        int port = getArgsInt(args, 5,8068);
        String basePackage = getArgsStr(args, 6,"com.join.wms.outstorage.init.server");
        Map<String, Object> param = new HashMap(){{
            put("schema", getArgsStr(args, 7, "wms-hz"));
            put("dbtype", getArgsInt(args, 8,2));
        }};
        GeneratorConfig config = GeneratorConfig.builder()
                .jdbcUrl(jdbcUrl)
                .userName(userName)
                .password(password)
                .driverClassName(driverClassName)
                .schemaName(schemaName)
                .port(port)
                .basePackage(basePackage)
                .templateParams(param)
                .nameConverter(new NameConverter() {
                    @Override
                    public String serviceNameConvert(String entityName) {
                        return entityName + "Service";
                    }

                    @Override
                    public String controllerNameConvert(String entityName) {
                        return entityName + "Controller";
                    }

                    @Override
                    public String entityNameConvert(String tableName, String tablePrefix) {
                        return StrUtil.upperFirst(StrUtil.toCamelCase(tableName.toLowerCase())) + "DTO";
                    }
                })
                .build();
        MybatisPlusToolsApplication.run(config);
    }

    private static int getArgsInt(String[] args, int i, int i1) {
        int value = i1;
        try {
            value = Optional.ofNullable(value).map(v -> Integer.valueOf(v)).orElse(i1);
        } catch (Exception e) {
        }
        return value;
    }

    private static String getArgsStr(String[] args, int index, String defaultValue) {
        String value = defaultValue;
        if (args.length > index) {
            value = args[index];
        }
        return Optional.ofNullable(value).orElse(defaultValue);
    }

    private static String getSchemaName(String driverClassName) {
        if(driverClassName == null){
            return null;
        }
        if(driverClassName.toLowerCase().contains("oracle")){
            return "ORACLE";
        } else {
            return null;
        }
    }

    public static void run(GeneratorConfig generatorConfig) {
        if (Strings.isNullOrEmpty(generatorConfig.getJdbcUrl())) {
            throw new IllegalArgumentException("jdbcUrl必须要设置");
        }
        MybatisPlusToolsApplication.generatorConfig = generatorConfig;
        Map<String, Object> props = Maps.newHashMap();
        new SpringApplicationBuilder()
                .properties(props)
                .sources(MybatisPlusToolsApplication.class)
                .run();
    }

    @Bean
    public WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> containerConfig(GeneratorConfig config) {
        return factory -> {
            if (config.getPort() != null) {
                factory.setPort(MybatisPlusToolsApplication.generatorConfig.getPort());
            } else {
                factory.setPort(8080);
            }
            factory.setContextPath("");
        };
    }

    @Bean
    public GeneratorConfig generatorConfig() {
        return MybatisPlusToolsApplication.generatorConfig;
    }


}

